package light;


import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.util.ArrayList;

public class Sprite {
	private Image image;
        private int x;
        private int y;
        private boolean flag;
        private double angle;                                                   //угол поворота
        private int w;                                                          //ширина
        private int h;                                                          //высота
        private int xc;                                                         //координаты центра
        private int yc;
        private int t;                                                         //тип объекта
        
        AffineTransform rot=new AffineTransform(); 

	public Sprite(Image image, int x1, int y1, int t1) {
		this.image = image;
                flag = false;
                x = x1;
                y = y1;
                t = t1;
                w = image.getWidth(null);
                h = image.getHeight(null);
                xc = x + w/2;
                yc = y + h/2;
                angle = 0;
	}
        
        public boolean intersect (Sprite rectangle){
            Area beamRectArea;
            Area enemyRectArea;
            Area overlapArea;
            
            beamRectArea = new Area(new Rectangle(x, y, w, h));
            enemyRectArea = new Area(new Rectangle(rectangle.getX(), rectangle.getY(), rectangle.getWidth(), rectangle.getHeight()));
            
            AffineTransform atBeam = new AffineTransform();
            AffineTransform atEnemy = new AffineTransform();
 
            atBeam.rotate(Math.toRadians(angle));
            atEnemy.rotate(Math.toRadians(rectangle.getAngle()));
            beamRectArea.transform(atBeam);
            enemyRectArea.transform(atEnemy);
            
            overlapArea = (Area) enemyRectArea.clone();
            overlapArea.intersect(beamRectArea);
            return (!overlapArea.isEmpty());
        }
        
        public Point lineIntersect (Ray r){
            int tx;
            int ty;
            if (angle != 0){
                double dx = Math.sqrt(Math.pow(w/2,2) + Math.pow(h/2,2));
                dx = dx * Math.sin(Math.asin(2*dx/w) - angle);
                tx = xc - (int)dx;

                double dy = Math.sqrt(Math.pow(w/2,2) + Math.pow(h/2,2));
                dy = dy * Math.cos(Math.asin(2*dy/w) - angle);
                ty = yc - (int)dy;
            } else{
               tx = x;
               ty = y;
            }
            
            Point p = new Point(r.getX2(),r.getY2());
            Point pl1 = new Point(r.getX1(), r.getY1());                                        //первая точка прямой
            Point pl2 = new Point(r.getX2(), r.getY2());                                        //вторая точка прямой
            Point pv1 = new Point(tx,ty);                                                       //первая вершина прямоугольника
            Point pv2 = new Point((int)(tx + w * Math.sin(90 - angle)),                         //вторая вершина прямоугольника
                                  (int)(ty + w * Math.cos(90 - angle)));
            Point pv3 = new Point((int)(tx + w * Math.sin(90 - angle) - h * Math.sin(angle)), //третья вершина прямоугольника
                                  (int)(ty + h * Math.cos(angle) + w * Math.cos(90 - angle)));
            Point pv4 = new Point((int)(tx - h * Math.sin(angle)),                              //четвертая вершина прямоугольника
                                  (int)(ty + h * Math.cos(angle)));
            boolean f = false;
            ArrayList<Line> m = new ArrayList();
            Line ll = new Line(pl2,pl1);
            m.add(new Line(pv1,pv2));
            m.add(new Line(pv2,pv3));
            m.add(new Line(pv3,pv4));
            m.add(new Line(pv4,pv1));
            double k1 = (ll.y2 - ll.y1)/(ll.x2 - ll.x1);
            int z;                                                                          //промежуточные переменные для хранения значений x и y
            int q;
            for (int i = 0;i<m.size();i++){                                                     //вычисление точки пересечения линий
                Line l = m.get(i);
                if(l.x1 == l.x2){
                    z = l.x1;
                    q = (int)(k1*z - k1*ll.x1 + ll.y1);
                } else{
                    if (l.y1 == l.y2){
                        q = l.y1;
                        z = (int)(q/k1 - ll.y1/k1 + ll.x1);
                    } else{
                        double k2 = (l.y2 - l.y1)/(l.x2 - l.x1);
                        z = (int)((k1*ll.x1 - k2*l.x1 - ll.y1 + l.y1)/(k1 - k2));                       //x точки пересечения
                        q = (int)(k1*z - k1*ll.x1 + ll.y1);                                           //y точки пересечения
                    }
                }
                if (inside(z,q)){
                        if (Math.sqrt(Math.pow((z - pl1.x), 2) + Math.pow((q - pl1.y), 2)) 
                                < Math.sqrt(Math.pow((p.x - pl1.x), 2) + Math.pow((p.y - pl1.y), 2))){
                            f = true;
                            p.x = z;
                            p.y = q;
                        }
                }
                
            }
            if (!f){
                p.x = 600;
                p.y = (int)(k1*p.x - k1*ll.x1 + ll.y1);
            }
            return p;
        }
        
        public int getT(){
            return t;
        }
        public void setT(int t1){
            t = t1;
        }
        
        public int getXc(){
            return xc;
        }
        
        public int getYc(){
            return yc;
        }
                
        public double getAngle(){
            return angle;
        }
        
        public void setAngle(double angle1){
            angle = angle1;
        }

	public int getWidth() {
		return w;
	}

	public int getHeight() {
		return h;
	}
        
         public void setFlag(boolean flag1){
            flag = flag1;
        }
        
        public boolean getFlag(){
            return flag;
        }
        
        public void setX(int x1){
            x = x1;
            xc = x1 + w/2;
        }
        
        public void setY(int y1){
            y = y1;
            yc = y1 + h/2;
        }
        
        public int getX(){
            return x;
        }
        
        public int getY(){
            return y;
        }

	public Graphics draw(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            AffineTransform svan=g2.getTransform();
            rot.setToIdentity();
            rot.translate(xc, yc);
            rot.rotate(Math.toRadians(angle));
            rot.translate(-xc, -yc);
            g2.setTransform(rot);
            g = g2;
            
            int tx = x;
            int ty = y;
            g.drawImage(image,tx,ty,null);
            g2.setTransform(svan);
            g = g2;
            return g;
	}
        
    private boolean inside (int X, int Y){
        if (X < x || Y < y) {
            return false;
        }
        return ((x <= X && (w + x) > X) &&
                (y <= Y && (h + y) > Y));
    }

    private static class Line {
        
        
        public int x1;
        public int y1;
        public int x2;
        public int y2;

        public Line() {
            x1 = 0;
            y1 = 0;
            x2 = 0;
            y2 = 0;
        }
        
        public Line(int xs1, int ys1, int xs2, int ys2) {
            x1 = xs1;
            y1 = ys1;
            x2 = xs2;
            y2 = ys2;
        }
        public Line(Point p1, Point p2) {
            x1 = p1.x;
            y1 = p1.y;
            x2 = p2.x;
            y2 = p2.y;
        }
    }
}